﻿///<copyright>
/// Copyright © 2009 Stephen Styrchak. All Rights Reserved.
///</copyright>
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Ferpect.ComponentModel
{
    public class InputState
    {
        private PlayerIndex playerIndex;
        private KeyboardState currentKeyboard;
        private KeyboardState previousKeyboard;
        private GamePadState currentGamePad;
        private GamePadState previousGamePad;

        public InputState(PlayerIndex playerIndex)
        {
            if (playerIndex < PlayerIndex.One || PlayerIndex.Four < playerIndex)
            {
                throw new ArgumentOutOfRangeException("playerIndex");
            }
            this.playerIndex = playerIndex;
            this.Update();
            this.previousGamePad = this.currentGamePad;
            this.previousKeyboard = this.currentKeyboard;
        }

        public PlayerIndex PlayerIndex
        {
            get
            {
                return this.playerIndex;
            }
        }

        public GamePadButtons GetCurrentButtons()
        {
            return this.currentGamePad.Buttons;
        }

        public GamePadDPad GetCurrentDPad()
        {
            return this.currentGamePad.DPad;
        }

        public void GetCurrentThumbSticks(out GamePadThumbSticks thumbSticks)
        {
            thumbSticks = this.currentGamePad.ThumbSticks;
        }

        public void GetCurrentTriggers(out GamePadTriggers triggers)
        {
            triggers = this.currentGamePad.Triggers;
        }

        public Keys[] GetCurrentPressedKeys()
        {
            return this.currentKeyboard.GetPressedKeys();
        }

        public GamePadButtons GetPreviousButtons()
        {
            return this.previousGamePad.Buttons;
        }

        public GamePadDPad GetPreviousDPad()
        {
            return this.previousGamePad.DPad;
        }

        public Keys[] GetPreviousPressedKeys()
        {
            return this.previousKeyboard.GetPressedKeys();
        }

        public void GetPreviousThumbSticks(out GamePadThumbSticks thumbSticks)
        {
            thumbSticks = this.previousGamePad.ThumbSticks;
        }

        public void GetPreviousTriggers(out GamePadTriggers triggers)
        {
            triggers = this.previousGamePad.Triggers;
        }

        public bool IsButtonDown(Buttons button)
        {
            return this.currentGamePad.IsButtonDown(button);
        }

        public bool IsButtonUp(Buttons button)
        {
            return this.currentGamePad.IsButtonUp(button);
        }

        public bool IsKeyDown(Keys key)
        {
            return this.currentKeyboard.IsKeyDown(key);
        }

        public bool IsKeyUp(Keys key)
        {
            return this.currentKeyboard.IsKeyUp(key);
        }

        public bool IsNewButtonPress(Buttons buttons)
        {
            return this.currentGamePad.IsButtonDown(buttons) && !this.previousGamePad.IsButtonDown(buttons);
        }

        public bool IsNewButtonRelease(Buttons buttons)
        {
            return this.currentGamePad.IsButtonUp(buttons) && !this.previousGamePad.IsButtonUp(buttons);
        }

        public bool IsNewKeyPress(Keys keys)
        {
            return this.currentKeyboard.IsKeyDown(keys) && !this.previousKeyboard.IsKeyDown(keys);
        }

        public bool IsNewKeyRelease(Keys keys)
        {
            return this.currentKeyboard.IsKeyUp(keys) && !this.previousKeyboard.IsKeyUp(keys);
        }

        public bool IsConnected
        {
            get { return this.currentGamePad.IsConnected; }
        }

        public virtual void Update()
        {
            this.previousGamePad = this.currentGamePad;
            
            this.currentGamePad = GamePad.GetState(this.playerIndex);

#if !WINDOWS
            this.previousKeyboard = this.currentKeyboard;
            this.currentKeyboard = Keyboard.GetState(this.playerIndex);
#endif
        }
    }
}
